package me.sealer.ssm.service.impl;

import me.sealer.ssm.mapper.MenuMapper;
import me.sealer.ssm.mapper.RoleMapper;
import me.sealer.ssm.mapper.RoleMenuMapper;
import me.sealer.ssm.mapper.UserMapper;
import me.sealer.ssm.mapper.UserRoleMapper;
import me.sealer.ssm.model.Menu;
import me.sealer.ssm.model.Role;
import me.sealer.ssm.model.RoleExample;
import me.sealer.ssm.model.RoleMenu;
import me.sealer.ssm.model.RoleMenuExample;
import me.sealer.ssm.model.User;
import me.sealer.ssm.model.UserExample;
import me.sealer.ssm.model.UserRole;
import me.sealer.ssm.model.UserRoleExample;
import me.sealer.ssm.service.UserMenuService;
import org.apache.shiro.util.Assert;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author sealer
 * @date 2017/07/11
 */
@Service
public class UserMenuServiceImpl implements UserMenuService {

    private final UserMapper userMapper;
    private final UserRoleMapper userRoleMapper;
    private final RoleMenuMapper roleMenuMapper;
    private final RoleMapper roleMapper;
    private final MenuMapper menuMapper;

    public UserMenuServiceImpl(UserMapper userMapper, UserRoleMapper userRoleMapper, RoleMenuMapper roleMenuMapper, RoleMapper roleMapper, MenuMapper menuMapper) {
        this.userMapper = userMapper;
        this.userRoleMapper = userRoleMapper;
        this.roleMenuMapper = roleMenuMapper;
        this.roleMapper = roleMapper;
        this.menuMapper = menuMapper;
    }

    @Override
    public List<Menu> getMenusByUsername(String username) {
        // 根据用户名获取用户id
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUsernameEqualTo(username);
        List<User> users = userMapper.selectByExample(userExample);

        if (users.size() == 0) {
            return null;
        }

        Assert.isTrue(users.size() == 1, "脏数据异常");

        User user = users.get(0);

        // userRoles
        UserRoleExample userRoleExample = new UserRoleExample();
        userRoleExample.createCriteria().andUserIdEqualTo(user.getId());
        List<UserRole> userRoles = userRoleMapper.selectByExample(userRoleExample);

        // roles
        RoleExample roleExample = new RoleExample();
        roleExample.createCriteria().andIdIn(userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList()));
        List<Role> roles = roleMapper.selectByExample(roleExample);

        Set<Menu> menuSet = new HashSet<>();
        roles.forEach(role -> {
            // roleMenus
            RoleMenuExample roleMenuExample = new RoleMenuExample();
            roleMenuExample.createCriteria().andRoleIdEqualTo(role.getId());
            List<RoleMenu> roleMenus = roleMenuMapper.selectByExample(roleMenuExample);

            if (CollectionUtils.isEmpty(roleMenus)) {
                return;
            }

            // 根据roleMenus获取菜单列表
            List<Menu> ms = menuMapper.selectByIds(roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList()));

            menuSet.addAll(ms);
        });

        List<Menu> list = new ArrayList<>(menuSet);
        list.sort((Comparator.comparingInt(Menu::getId)));

        return list;
    }
}
